module add_sub(x,y,clk,out,op);
	input [15:0]x,y;			// 输入浮点数
	input op;					// 执行加法还是减法
	output reg[15:0]out;			// 输出浮点数
	input clk;					// 时钟信号
	reg	[4:0]xE,yE,zE;			// 五位阶码,移码表示
	reg [12:0]xF,yF,zF;			// 1位数符+10位尾数+1位进位符+1位前置1
	reg [2:0] state;			// 状态变量
	wire flag;					// 决定是否输出
	parameter START = 3'b000,ZEROCHECK= 3'b001,EQUAL_E = 3'b010,ADD= 3'b011,STANDER=3'b100,OVER=3'b101;
	
	assign flag = (state == OVER) ? 1 : 0;
	
	always@(posedge clk)
	begin
		if(flag == 1)
			out = {zF[12],zE[4:0],zF[9:0]};			// 当flag为1时，输出.
		case(state) 
		START:					// 提取出阶码和数符，尾数
		begin
			xE <= x[14:10];		// 阶码提取
			yE <= y[14:10];
			xF <= {x[15],1'b0,1'b1,x[9:0]};	// 从左到右分别是数符,进位的位,隐藏位,尾数
			if(op == 0)
				yF <= {y[15],1'b0,1'b1,y[9:0]};
			else if(op == 1)				// 如果是减法,y的符号位取反。
				yF <= {~y[15],1'b0,1'b1,y[9:0]};
			state <= ZEROCHECK;
		end
		ZEROCHECK:									// 检查x,y是否有一个是0
		begin
			if(x == 0)
			begin
				{zE,zF} <= {yE,yF};
				state <= OVER;
			end
			else if(y == 0)
			begin
				{zE,zF} <= {xE,xF};
				state <= OVER;
			end
			else
				state <= EQUAL_E;
		end
		EQUAL_E:								// 对阶操作
		begin
			if(xE == yE)						// 阶码相同，进入到尾数相加环节
				state <= ADD;
			else if(xE < yE)					//	如果x的阶码比较小
			begin
				xE <= xE + 1;					// x的阶码+1
				xF[11:0] <= {1'b0,xF[11:1]};		// x尾数右移,舍弃最低位
			end
			else if(yE < xE)					// 如果y的阶码比较小
			begin								// 同上
				yE <= yE + 1;
				yF[11:0] <= {1'b0,yF[11:1]};
			end
		end
		ADD:
		begin
			if((xF[12] ^ yF[12]) == 0)			// 同号的情况下
				begin
					zF[12] <= xF[12];
					zF[11:0] <= xF[11:0] + yF[11:0];
				end
			else if(xF[11:0] > yF[11:0])		// 异号并且x的绝对值较大
				begin
					zF[12] <= xF[12];
					zF[11:0] <= xF[11:0] - yF[11:0];
				end
			else if(xF[11:0] < yF[11:0])		// 异号并且y的绝对值较大
				begin
					zF[12] <= yF[12];
					zF[11:0] <= yF[11:0] - xF[11:0];
				end
			zE <= xE;
			state <= STANDER;
		end
		STANDER:							// 标准化过程
		begin
			if(zF[11] == 1)				// 有进位
				begin
					zE <= zE + 1;
					zF[11:0] = {1'b0,zF[11:1]};	// 右移一位
				end
			else if(zF[10] == 0)				// 最高位不是1
				begin
					zE <= zE - 1;
					zF[11:0] <= {zF[10:0],1'b0};	// 左移一位
				end
			else
				state <= OVER;
		end
		OVER:
			state <= START;
		default:
			state <= START;
		endcase
	end
	
endmodule